package eteam.aps.controller;

import eteam.aps.common.R;
import eteam.aps.common.component.LoginUserRedisService;
import eteam.aps.common.entity.ParentEntity;
import eteam.aps.common.exceptions.AuthException;
import eteam.aps.common.exceptions.BusinessException;
import eteam.aps.common.helper.Helper;
import eteam.aps.common.helper.JsonPage;
import eteam.aps.model.dto.ProductInfoDto;
import eteam.aps.model.entity.*;
import eteam.aps.model.vo.DataDictionaryCategoryTreeVo;
import eteam.aps.model.vo.ProductCategoryTreeVo;
import eteam.aps.model.vo.ProductInfoListVo;
import eteam.aps.model.vo.ProductInfoVo;
import eteam.aps.service.*;
import eteam.aps.systeminterface.model.dto.VerifyTokenDto;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;

import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 产品信息控制层
 *
 * @author WMT
 */
@Api(tags = "产品信息模块")
@RestController
public class ProductInfoController implements IProductInfoController {

    @Autowired
    private ProductInfoService productInfoService;

    @Autowired
    private ProductParamService productParamService;

    @Autowired
    private ProductCategoryService productCategoryService;

    @Autowired
    private ProductParamHistoryService paramHistoryService;

    @Autowired
    private ProductParamHistoryDtlService paramHistoryDtlService;

    @Autowired
    private DataDictionaryCategoryService dataDictionaryCategoryService;

    @Autowired
    private OnlyProductService onlyProductService;

    @Autowired
    private QueryInfoService queryInfoService;

    @Autowired
    private LoginUserRedisService loginUserRedisService;

    @Override
    @ApiOperation("新增产品")
    @PostMapping("/pe/insert")
    public R<Integer> insert(@RequestBody ProductInfoDto productInfoDto) throws Exception, AuthException {
        // 设置用户和部门信息
        VerifyTokenDto user = loginUserRedisService.getUser();
        productInfoDto.setfCreateUserId(user.getFuserid());
        productInfoDto.setfLastModifyUserId(user.getFuserid());
        productInfoDto.setfBookCode(user.getFgrouporgid());
        String fId = Helper.GetId();
        productInfoDto.setfId(fId);
        productInfoDto.setfState(ProductParentEntity.FSTATE_DRAFT);
        LocalDateTime now = LocalDateTime.now();
        productInfoDto.setfCreatorTime(now);
        productInfoDto.setfLastModifyTime(now);

        if (Helper.isEmpty(productInfoDto.getfPcId())) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "请先选择产品分类");
        }
        if (Helper.isEmpty(productInfoDto.getfEquipCode()) || Helper.isEmpty(productInfoDto.getfEquipName())) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品编号或产品名称不能为空");
        }
        if (Helper.isEmpty(productInfoDto.getfProductAffiliation())) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "所属单位不能为空");
        }
        if (Helper.isEmpty(productInfoDto.getfProductUnit())) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品单位不能为空");
        }
        if (Helper.isEmpty(productInfoDto.getfProductSpec())) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品规格不能为空");
        }
        if (Helper.isEmpty(productInfoDto.getfProductModel())) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品型号不能为空");
        }
        if (productInfoService.selectCountByPeCode(productInfoDto.getfEquipCode()) > 0) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品编号已存在");
        }
        if (productInfoService.selectCountByPeName(productInfoDto.getfEquipName()) > 0) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品名称已存在");
        }

        // 装备参数列表赋值
        String paramInfo = "";
        List<ProductParam> productParams = productInfoDto.getProductParams();
        if (productParams != null) {
            for (ProductParam param : productParams) {

                paramInfo += setParamInfo(param.getfParamName(), param.getfParamCode());
                productInfoDto.setfPpInfo(paramInfo);

                param.setfId(Helper.GetId());
                param.setfDtlId(fId);
                param.setfState(ParentEntity.FSTATE_DRAFT);
                param.setfCreateUserId(user.getFuserid());
                param.setfCreatorTime(now);
                param.setfLastModifyUserId(user.getFuserid());
                param.setfLastModifyTime(now);
                param.setfBookCode(user.getFgrouporgid());

                List<ProductParam> params = new ArrayList<>();
                params.add(param);
                productParamService.insert(params);

                // 添加产品参数记录
                ProductParamHistory productParamHistory = new ProductParamHistory();
                BeanUtils.copyProperties(param, productParamHistory);
                productParamHistory.setfPpId(param.getfId());
                paramHistoryService.insert(productParamHistory);
                ProductParamHistoryDtl productParamHistoryDtl = new ProductParamHistoryDtl();
                productParamHistoryDtl.setfDtlId(productParamHistory.getfId());
                productParamHistoryDtl.setfProductId(fId);
                BeanUtils.copyProperties(param, productParamHistoryDtl);
                paramHistoryDtlService.insert(productParamHistoryDtl);
            }
        }

        OnlyProduct onlyProduct = new OnlyProduct();
        BeanUtils.copyProperties(productInfoDto, onlyProduct);
        onlyProduct.setfProductCode(productInfoDto.getfEquipCode());
        onlyProduct.setfProductName(productInfoDto.getfEquipName());
        onlyProduct.setfFlag(ProductParentEntity.FFLAG_INIT);
        onlyProductService.insert(onlyProduct);

        return R.success(productInfoService.insert(productInfoDto));
    }

    @Override
    @ApiOperation("删除产品")
    @PostMapping("/pe/delete/{fId}")
    public R<Integer> delete(@PathVariable String fId) throws Exception, AuthException {
        if (Helper.isEmpty(fId)) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品fId不能为空");
        }
        ProductInfo productInfoDb = productInfoService.selectByFId(fId);
        if (productInfoDb == null) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品不存在");
        }
        if (productInfoService.selectFStateByFId(fId) == ProductParentEntity.FSTATE_DELETED) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品已被删除");
        }

        // 删除装备时，需要把产品参数子表的数据删除
        productParamService.deleteByFDtlId(fId);
        return R.success(productInfoService.delete(fId));
    }

    @Override
    @ApiOperation("修改产品")
    @PostMapping("/pe/update")
    public R<Integer> update(@RequestBody ProductInfoDto productInfoDto) throws Exception, AuthException {

        // 设置最后修改人
        VerifyTokenDto user = loginUserRedisService.getUser();
        productInfoDto.setfLastModifyUserId(user.getFuserid());
        LocalDateTime now = LocalDateTime.now();
        productInfoDto.setfLastModifyTime(now);

        if (Helper.isEmpty(productInfoDto.getfPcId())) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "请先选择产品分类");
        }
        if (Helper.isEmpty(productInfoDto.getfId())) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品fId为空");
        }
        if (Helper.isEmpty(productInfoDto.getfEquipCode()) || Helper.isEmpty(productInfoDto.getfEquipName())) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品编号或产品名称不能为空");
        }

        ProductInfo equipInfoDb = productInfoService.selectByFId(productInfoDto.getfId());
        if (!productInfoDto.getfEquipCode().equals(equipInfoDb.getfEquipCode())) {
            if (productInfoService.selectCountByPeCode(productInfoDto.getfEquipCode()) > 0) {
                throw new BusinessException(HttpStatus.BAD_REQUEST, "产品编号已存在");
            }
        }
        if (!productInfoDto.getfEquipName().equals(equipInfoDb.getfEquipName())) {
            if (productInfoService.selectCountByPeName(productInfoDto.getfEquipName()) > 0) {
                throw new BusinessException(HttpStatus.BAD_REQUEST, "产品名称已存在");
            }
        }

        List<ProductParam> productParams = productInfoDto.getProductParams();
        if (productParams != null) {
            for (ProductParam param : productParams) {
                param.setfLastModifyUserId(user.getFuserid());
                param.setfLastModifyTime(now);
                productParamService.update(param);

                Map<String, Object> map = new HashMap<>();
                map.put("fDtlId", productInfoDto.getfId());
                map.put("fParamCode", param.getfParamCode());
                if (!(productParamService.countCodeByFDtlId(map) > 0)) {
                    param.setfId(Helper.GetId());
                    param.setfDtlId(productInfoDto.getfId());
                    param.setfState(ProductParentEntity.FSTATE_DRAFT);
                    param.setfCreateUserId(user.getFuserid());
                    param.setfCreatorTime(now);
                    param.setfLastModifyTime(now);
                    param.setfBookCode(user.getFgrouporgid());

                    List<ProductParam> params = new ArrayList<>();
                    params.add(param);
                    productParamService.insert(params);
                }
            }
        }

        OnlyProduct onlyProductDb = onlyProductService.selectByCode(Helper.likeSql(productInfoDto.getfEquipCode()));
        int count = 0;
        if (onlyProductDb != null) {
            BeanUtils.copyProperties(productInfoDto, onlyProductDb);
            String code = onlyProductDb.getfProductCode();
            if (code.contains(".")){
                String versionDb = code.substring(code.lastIndexOf(".")+1);
                count = Integer.parseInt(versionDb);
            }
            String version = new DecimalFormat("0000").format(++count);
            if (version.length() > 4) {
                throw new BusinessException(HttpStatus.BAD_REQUEST, "产品版本号过长");
            }
            onlyProductDb.setfCreateUserId(user.getFuserid());
            onlyProductDb.setfLastModifyUserId(user.getFuserid());
            onlyProductDb.setfBookCode(user.getFgrouporgid());
            onlyProductDb.setfId(Helper.GetId());
            onlyProductDb.setfState(ProductParentEntity.FSTATE_DRAFT);
            onlyProductDb.setfCreatorTime(now);
            onlyProductDb.setfLastModifyTime(now);
            onlyProductDb.setfProductCode(productInfoDto.getfEquipCode() + "." + version);
            onlyProductDb.setfProductName(productInfoDto.getfEquipName());
            onlyProductDb.setfFlag(ProductParentEntity.FFLAG_UPDATE);
            onlyProductService.insert(onlyProductDb);
        }
        return R.success(productInfoService.update(productInfoDto));
    }

    @Override
    @ApiOperation("分页查询产品")
    @PostMapping("/pe/selectAll")
    public R<JsonPage<ProductInfoListVo>> selectAll(
            @RequestParam("fPcId") String fPcId,
            @RequestParam(value = "fEquipCode", required = false) String fEquipCode,
            @RequestParam(value = "fEquipName", required = false) String fEquipName,
            @RequestParam("page") Integer page, @RequestParam("pageSize") Integer pageSize,
            @RequestParam("fProductCategory") Integer fProductCategory
    ) throws Exception, AuthException {
        if ((Helper.trim(fPcId)) == null) {
            throw new IllegalArgumentException("请先选择产品类别");
        }
        Map<String, Object> map = new HashMap<String, Object>(4);
        map.put("fPcId", fPcId);
        if (Helper.isNotEmpty(fEquipCode)) {
            map.put("fEquipCode", Helper.likeSql(fEquipCode));
        }
        if (Helper.isNotEmpty(fEquipName)) {
            map.put("fEquipName", Helper.likeSql(fEquipName));
        }

        JsonPage<ProductInfoListVo> jsonPage = productInfoService.selectAll(map, Helper.valuePositive(page, 1),
                Helper.valuePositive(pageSize, 10), fProductCategory);
        for (ProductInfoListVo listVo : jsonPage.getList()) {
            listVo.setfProductAffName(queryInfoService.selectProducerName().get(listVo.getfProductAffiliation()));
            listVo.setfProductModelName(queryInfoService.selectModelName().get(listVo.getfProductModel()));
            listVo.setfProductUnitName(queryInfoService.selectUnitName().get(listVo.getfProductUnit()));
        }
        return R.success(jsonPage);
    }

    @Override
    @ApiOperation("查询产品详情")
    @PostMapping("/pe/selectDetails/{fId}")
    public R<List<ProductInfoVo>> selectDetails(@PathVariable String fId) throws Exception, AuthException {
        if (Helper.isEmpty(fId)) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品fId不能为空");
        }
        ProductInfo equipInfoDb = productInfoService.selectByFId(fId);
        if (equipInfoDb == null) {
            throw new BusinessException(HttpStatus.BAD_REQUEST, "产品不存在");
        }
        List<ProductInfoVo> productInfoVos = productInfoService.selectDetails(fId);
        for (ProductInfoVo productInfoVo : productInfoVos) {
            productInfoVo.setfProductAffName(queryInfoService.selectProducerName().get(productInfoVo.getfProductAffiliation()));
            productInfoVo.setfProductModelName(queryInfoService.selectModelName().get(productInfoVo.getfProductModel()));
            productInfoVo.setfProductUnitName(queryInfoService.selectUnitName().get(productInfoVo.getfProductUnit()));
        }
        return R.success(productInfoVos);
    }

    @Override
    @ApiOperation("查询产品分类目录树")
    @PostMapping("/pe/selectEcTree/{fPcAffProduct}")
    public R<List<ProductCategoryTreeVo>> selectEcTree(@PathVariable int fPcAffProduct) throws Exception, AuthException {
        return R.success(productCategoryService.selectEcTree(fPcAffProduct));
    }

    @Override
    @ApiOperation("选择产品型号")
    @PostMapping("/pe/setModel")
    public R<List<DataDictionaryCategoryTreeVo>> selectDdcSetModel() throws Exception, AuthException {
        return R.success(dataDictionaryCategoryService.selectFDdcTree());
    }

    @Override
    @ApiOperation("启用序列号管理")
    @PostMapping("/pe/setEnable/{fId}")
    public R<Integer> setEnable(@PathVariable String fId) throws Exception, AuthException {
        return R.success(productInfoService.setEnable(fId));
    }

    @Override
    @ApiOperation("禁用序列号管理")
    @PostMapping("/pe/setDisable/{fId}")
    public R<Integer> setDisable(@PathVariable String fId) throws Exception, AuthException {
        return R.success(productInfoService.setDisable(fId));
    }

    @Override
    @ApiOperation("查询装备列表")
    @PostMapping("/pe/equipList")
    public R<List<ProductInfoVo>> selectEquipList() throws Exception, AuthException {
        return R.success(productInfoService.selectEquipList());
    }

    /**
     * 设置参数详情
     *
     * @param name 参数子表name
     * @param code 参数子表code
     * @return 参数子表name和参数子表code拼接的字符串
     */
    private String setParamInfo(String name, String code) {
        return new StringBuilder().append(name).append(code).append(";").toString();
    }


}
